package com.suntront.module_bluetooth

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import com.mtjsoft.www.kotlinmvputils.utils.HHTipUtils
import com.mtjsoft.www.kotlinmvputils.utils.KLog
import com.suntront.module_bluetooth.model.BlueToothModel
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.OutputStream
import java.nio.charset.Charset
import java.util.*
import kotlin.collections.ArrayList


class BlueToothTool private constructor() {
    companion object {
        val uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")

        var bluetoothSocket: BluetoothSocket? = null
        var outputStream: OutputStream? = null

        val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()

        val instance: BlueToothTool by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            BlueToothTool()
        }
    }

    /**
     * 获取蓝牙监听广播
     */
    fun getBlueToothIntentFilter(): IntentFilter {
        val intentFilter = IntentFilter()
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND)
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED)
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
        // 监视蓝牙关闭和打开的状态
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
        // 监视蓝牙设备与APP连接的状态
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
        return intentFilter
    }

    /**
     * 蓝牙是否可用
     */
    fun getBluetoothIsCanUse(): Boolean {
        return bluetoothAdapter != null
    }

    /**
     * 蓝牙是否打开
     */
    fun getBluetoothIsOpen(): Boolean {
        if (bluetoothAdapter == null) {
            return false
        }
        return bluetoothAdapter.isEnabled
    }

    /**
     * 获取已配对的蓝牙设备
     */
    fun getBondedDevices(): MutableList<BlueToothModel> {
        val list: MutableList<BlueToothModel> = ArrayList()
        if (bluetoothAdapter != null) {
            val set = bluetoothAdapter.bondedDevices
            if (set != null && set.size > 0) {
                val blueToothModel = BlueToothModel()
                blueToothModel.name = "已配对："
                blueToothModel.setItemType(BlueToothModel.TITLE_TYPE)
                list.add(blueToothModel)
                for (item in set) {
                    val model = BlueToothModel()
                    model.name = item.name
                    model.address = item.address
                    model.bondState = item.bondState
                    model.type = item.type
                    model.setItemType(BlueToothModel.CONTENT_TYPE)
                    list.add(model)
                }
            }
        }
        return list
    }

    /**
     * 开始扫描设备
     */
    fun startDiscovery() {
        if (bluetoothAdapter != null) {
            if (bluetoothAdapter.isDiscovering) {
                bluetoothAdapter.cancelDiscovery()
            }
            bluetoothAdapter.startDiscovery()
        }
    }

    /**
     * 停止扫描设备
     */
    fun cancelDiscovery() {
        if (bluetoothAdapter != null && bluetoothAdapter.isDiscovering) {
            bluetoothAdapter.cancelDiscovery()
        }
    }

    /**
     * 点击开始请求配对
     */
    fun createBond(device: BluetoothDevice) {
        val method = BluetoothDevice::class.java.getMethod("createBond")
        method.invoke(device)
    }

    /**
     * 取消配对
     */
    fun removeBond(device: BluetoothDevice) {
        val method = BluetoothDevice::class.java.getMethod("removeBond")
        method.invoke(device)
    }

    /**
     * 连接蓝牙
     */
    fun connect(device: BluetoothDevice, uuid: UUID): Boolean {
        // 先取消扫描，关闭之前的连接
        try {
            cancelDiscovery()
            close()
            bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid)
            if (bluetoothSocket != null) {
                bluetoothSocket!!.connect()
                outputStream = bluetoothSocket!!.outputStream
                MMKV.defaultMMKV().encode("bluetooth_address", device.address)
                KLog.e("mtj", "连接蓝牙成功：${device.address}")
                return true
            }
        } catch (e: Exception) {
        }
        return false
    }

    /**
     * 关闭蓝牙
     */
    fun close() {
        if (bluetoothSocket != null && bluetoothSocket!!.isConnected) {
            bluetoothSocket!!.close()
            bluetoothSocket = null
        }
        if (outputStream != null) {
            outputStream!!.close()
            outputStream = null
        }
    }

    /**
     * 蓝牙发送数据
     */
    fun sendBluetoothMsg(msg: String, activity: AppCompatActivity) {
        try {
            if (!getBluetoothIsCanUse()) {
                HHTipUtils.getInstance().showToast(activity.baseContext, "设备不支持蓝牙")
                return
            }
            if (!getBluetoothIsOpen()) {
                HHTipUtils.getInstance().showToast(activity.baseContext, "蓝牙未开启")
                return
            }
            val bluetooth_address = MMKV.defaultMMKV().decodeString("bluetooth_address", "")
            if (bluetooth_address.isEmpty()) {
                HHTipUtils.getInstance().showToast(activity.baseContext, "蓝牙未配对")
                return
            }
            if (outputStream == null) {
                HHTipUtils.getInstance().showProgressDialog(activity.baseContext, "正在连接蓝牙...")
                val job = GlobalScope.launch {
                    val b = connect(
                        bluetoothAdapter!!.getRemoteDevice(
                            bluetooth_address
                        ), uuid
                    )
                    withContext(Dispatchers.Main) {
                        HHTipUtils.getInstance().dismissProgressDialog()
                        if (b) {
                            sendBluetoothMsg(msg)
                        } else {
                            HHTipUtils.getInstance().showToast(activity.baseContext, "蓝牙连接失败")
                        }
                    }
                }
                // 界面销毁，取消协程
                activity.lifecycle.addObserver(object : LifecycleObserver {
                    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
                    fun onDestroy(owner: LifecycleOwner) {
                        job.cancel()
                        HHTipUtils.getInstance().dismissProgressDialog()
                    }
                })
            } else {
                sendBluetoothMsg(msg)
            }
        } catch (e: Exception) {
            if (!activity.isDestroyed) {
                HHTipUtils.getInstance().showToast(activity.baseContext, "发送蓝牙数据失败")
            }
        }
    }

    private fun sendBluetoothMsg(msg: String) {
        val byte = msg.toByteArray(Charset.forName("gbk"))
        if (bluetoothSocket != null && bluetoothSocket!!.isConnected && outputStream != null) {
            outputStream!!.write(byte, 0, byte.size)
            outputStream!!.flush()
        }
        KLog.e("mtj", "发送蓝牙数据成功: $msg")
    }

    /**
     * 设置打印样式
     */
    fun setBluetoothStyle(byte: ByteArray) {
        try {
            if (bluetoothSocket != null && bluetoothSocket!!.isConnected && outputStream != null) {
                outputStream!!.write(byte)
                outputStream!!.flush()
            }
        } catch (e: Exception) {
        }
    }
}